// index.js
function MyWavesurfer(options) {
	var container = options.wavesurfer.container,
		url = options.wavesurfer.url,
		waveColor = options.wavesurfer.waveColor,
		progressColor = options.wavesurfer.progressColor,
		flagArr = options.wavesurfer.flagArr || [],
		regionArr = options.region.regionArr,
		speedArr = options.wavesurfer.speedArr || [0.5, 1, 2],
		processOnHandler = options.wavesurfer.processOnHandler,
		flagClickHandler = options.wavesurfer.flagClickHandler,
		wavesurferClickHandler = options.wavesurfer.wavesurferClickHandler;
		
	this.timestamp = new Date().getTime();
	this.flagArr = flagArr;
	this.url = url;
	this.regionArr = regionArr;
	this.renderDom(document.querySelector(container), speedArr);
	this.processOnHandler = processOnHandler;
	this.clickHandler = wavesurferClickHandler;
	this.flagClickHandler = flagClickHandler;
	
	this.wavesurfer = this.create(waveColor, progressColor);
	this.load();
	this.initEvent();
	
}

MyWavesurfer.prototype.renderDom = function(parent, speedArr) {
	var timestamp = this.timestamp;
	if(parent == null) {
		var body = document.querySelector("body");
		var parantNode = document.createElement("div");
		parantNode.setAttribute("id", "parent-" + timestamp);
		body.appendChild(parentNode);
		parent = parentNode;
	}
	this.parent = parent;
	if(speedArr == null) {
		speedArr = [];
	}
	// ws-container DOM
	var containerDOM = document.createElement('div');
	containerDOM.setAttribute("id", "ws-container-"+timestamp);
	containerDOM.setAttribute("class", "ws-container");
	
	// ----------------------------------------------------------
	// ws-tools DOM
	var toolsDOM = document.createElement('div');
	toolsDOM.setAttribute("class", "ws-tools");
	
	// ws-tools childDom
	var startIcon = document.createElement('i');
	startIcon.setAttribute("class", "iconfont icon-start");
	var stopIcon = document.createElement('i');
	stopIcon.setAttribute("class", "iconfont icon-stop");
	
	var brDom = document.createElement('br');
	
	var zoomDOM = document.createElement('div');
	zoomDOM.setAttribute("class", "zoom");
	var zoomIn = document.createElement('i');
	zoomIn.setAttribute("class", "iconfont icon-zoomin");
	var zoomOut = document.createElement('i');
	zoomOut.setAttribute("class", "iconfont icon-zoomout");
	
	zoomDOM.appendChild(zoomIn);
	zoomDOM.appendChild(zoomOut);
	
	toolsDOM.appendChild(startIcon);
	toolsDOM.appendChild(stopIcon);
	toolsDOM.appendChild(brDom);
	toolsDOM.appendChild(zoomDOM);
	
	// ws-right DOM
	var wsRightDom = document.createElement('div');
	wsRightDom.setAttribute("class", "ws-right");
	
	// ws-time
	var timeDOM = document.createElement('div');
	timeDOM.setAttribute("class", "ws-time");
	timeDOM.innerHTML = '<span id="currentTime-'+ timestamp +'"></span> / <span id="totalTime-'+ timestamp +'"></span>';
	
	var settingsDOM = document.createElement('div');
	settingsDOM.setAttribute('class', "ws-settings");
	
	var speedSelector = document.createElement('select');
	speedSelector.setAttribute('class', "setting-speed");
	speedArr.forEach(function(item){
		var optionItem = document.createElement('option');
		optionItem.setAttribute("value", item);
		if(Number(item) == 1) {
			optionItem.setAttribute("selected", "selected");
		}
		optionItem.innerText = item + '倍速';
		speedSelector.appendChild(optionItem);
	})
	settingsDOM.appendChild(speedSelector);
	
	wsRightDom.appendChild(timeDOM);
	wsRightDom.appendChild(settingsDOM);
	
	// ws-outer
	var wsOuterDom = document.createElement('div');
	wsOuterDom.setAttribute("class", "ws-outer");
	
	var timelineDom = document.createElement('div');
	timelineDom.setAttribute("id", "timeline-" + timestamp);
	timelineDom.setAttribute("class", "timeline");
	var wavesurferDom = document.createElement('div');
	wavesurferDom.setAttribute("id", "c-wavesurfer-" + timestamp);
	wavesurferDom.setAttribute("class", "c-wavesurfer");
	
	wsOuterDom.appendChild(timelineDom);
	wsOuterDom.appendChild(wavesurferDom);
	
	containerDOM.appendChild(toolsDOM);
	containerDOM.appendChild(wsRightDom);
	containerDOM.appendChild(wsOuterDom);
	
	parent.appendChild(containerDOM);
}

MyWavesurfer.prototype.create = function(waveColor, progressColor) {
	var container = this.container, timestamp = this.timestamp;
	var wavesurfer = WaveSurfer.create({
		container: "#c-wavesurfer-" + timestamp,
		waveColor: waveColor || 'rgba(102,102,102,.6)',
		progressColor: progressColor || '#3B8686',
		backend: 'MediaElement',
		height: 100,
		plugins: [
			WaveSurfer.regions.create({
				regions: []
			}),
			WaveSurfer.timeline.create({
				container: '#timeline-' + timestamp,
				height: 12,
				fontSize: 12,
				formatTimeCallback: function(sec, pxPerSec) {
					return MyWavesurfer.TimeFormat(sec);
				}
			})
		]
	})
	
	return wavesurfer;
}

MyWavesurfer.prototype.load = function() {
	this.wavesurfer.load(this.url);
}

MyWavesurfer.prototype.initEvent = function() {
	var that = this;
		wavesurfer = this.wavesurfer, 
		scale = this.scale, 
		regionArr = this.regionArr;
	
	wavesurfer.on('ready', function() {
		// console.log("duration", this.wavesurfer.getDuration());
		duration = wavesurfer.getDuration();
		var maxCanvasWidth = wavesurfer.params.maxCanvasWidth;
		// console.log("params", wavesurfer.params);
		minPxPerSec = wavesurfer.params.minPxPerSec;
		that.scale = maxCanvasWidth / 3 / duration;
		that.initScale = maxCanvasWidth / 3 / duration;
		// console.log("init scale=", { minPxPerSec, duration, maxCanvasWidth, scale: that.scale });
		// console.log("init scale=", { minPxPerSec, duration, maxCanvasWidth, scale: that.scale });
		totalTime = MyWavesurfer.TimeFormat(duration);
		that.parent.querySelector('#totalTime-'+that.timestamp).innerText = totalTime;
		that.parent.querySelector('#currentTime-'+that.timestamp).innerText = "00:00:00";
		that.renderFlag();
		that.addEventListener();
		// console.log("init scale=", { minPxPerSec, duration, maxCanvasWidth });
	})
	
	wavesurfer.on('pause', function() {
		that.parent.querySelector(".icon-start").style.display = "inline-block";
		that.parent.querySelector(".icon-stop").style.display = "none";
	})
	
	wavesurfer.on('play', function() {
		that.parent.querySelector(".icon-stop").style.display = "inline-block";
		that.parent.querySelector(".icon-start").style.display = "none";
	});
	
	wavesurfer.on('audioprocess', function() {
		// console.log("audioprocess");
		var currentTime = wavesurfer.getCurrentTime();
		that.parent.querySelector('#currentTime-'+ that.timestamp).innerText = MyWavesurfer.TimeFormat(currentTime);
		
		wavesurfer.clearRegions();
		
		regionArr.forEach(function(item) {
			var startTime = MyWavesurfer.GetTimeFloat(item.start),
				endTime = MyWavesurfer.GetTimeFloat(item.end);
			if(startTime <= currentTime 
				&& endTime > currentTime) {
				
				wavesurfer.addRegion({
					start: startTime,
					end: endTime,
					color: item.color || "rgba(102, 102, 102, .3)"
				});
			}
		});
		if(this.processOnHandler) {
			this.processOnHandler({
				currnetTime: MyWavesurfer.TimeFormat(currentTime)
			});
		}
		
		// console.log("regionIns", wavesurfer);
	})
	
	wavesurfer.on('zoom', function() {
		// console.log("zoom parent:", that.parent);
		that.renderFlag(that.flagArr);
	})
}

MyWavesurfer.prototype.setCurrentTime = function(currentTime) {
	this.wavesurfer.seekTo(0);
	this.wavesurfer.skip(MyWavesurfer.GetTimeFloat(currentTime));
	this.parent.querySelector('#currentTime-'+ this.timestamp).innerText = MyWavesurfer.TimeFormat(MyWavesurfer.GetTimeFloat(currentTime));
}

MyWavesurfer.prototype.addEventListener = function() {
	var that = this;
	this.parent.querySelector(".icon-start").addEventListener('click', that.togglePlay.bind(that));
	this.parent.querySelector(".icon-stop").addEventListener('click', that.togglePlay.bind(that));
	this.parent.querySelector(".icon-zoomin").addEventListener('click', that.zoom.bind(that, 2));
	this.parent.querySelector(".icon-zoomout").addEventListener('click', that.zoom.bind(that, 0.5));
	this.parent.querySelector(".setting-speed").addEventListener('change', that.handleSpeedChange.bind(that));
	this.parent.querySelector('#wave-flags-'+ that.timestamp).addEventListener('click', that.wavesurferClickHandler.bind(that)); // 
}

MyWavesurfer.prototype.wavesurferClickHandler = function(event) {
	// console.log("wavesurferClickHandler", event.layerX);
	var totalWidth = this.parent.querySelector('#wave-flags-'+ this.timestamp).offsetWidth;
	// console.log("wavesurferClickHandler", {layerX: event.layerX, totalWidth, duration: this.wavesurfer.getDuration()});
	var currentTime = this.wavesurfer.getDuration() * event.layerX / totalWidth;
	// console.log("currentTime", currentTime);
	this.parent.querySelector('#currentTime-'+ this.timestamp).innerText = MyWavesurfer.TimeFormat(currentTime);
	if(this.clickHandler) {
		this.clickHandler(MyWavesurfer.TimeFormat(currentTime));
	}
}

MyWavesurfer.prototype.togglePlay = function() {
	this.wavesurfer.playPause();
}

MyWavesurfer.prototype.handleSpeedChange = function() {
	var speedSelector = this.parent.querySelector(".setting-speed");
	// console.log("handleSpeedChange", speedSelector.value);
	this.wavesurfer.setPlaybackRate(speedSelector.value);
}

MyWavesurfer.prototype.zoom = function(times) {
	// console.log("times", times);
	this.scale *= times;
	if(this.scale < this.initScale) {
		this.scale = this.initScale;
	}
	this.scale = Math.floor(this.scale / 10) * 10;
	// console.log("zoom scale=", {scale: Number(this.scale), duration });
	this.wavesurfer.zoom(Number(this.scale));
	this.renderFlag();
}

MyWavesurfer.prototype.renderFlag = function() {
	var canvasArr = this.parent.querySelectorAll('#c-wavesurfer-'+ this.timestamp +' > wave > canvas');
	// console.log("canvasArr", canvasArr);
	var canvasWidth = 0;
	Array.prototype.forEach.call(canvasArr, function(item) {
		canvasWidth += item.offsetWidth;
	})
	// console.log("canvasWidth", canvasWidth);
	// console.log("canvasWidth", canvasWidth);
	
	var flagContainer = null;
	
	var waveFlagsNode = this.parent.querySelector('#wave-flags-' + this.timestamp);
	if( waveFlagsNode != null) {
		waveFlagsNode.innerHTML = "";
		flagContainer = waveFlagsNode;
		flagContainer.setAttribute("style", "position:relative;height: 100px;width:" + canvasWidth + 'px;');
	}else {
		flagContainer = document.createElement('div');
		flagContainer.setAttribute("id", "wave-flags-" + this.timestamp);
		flagContainer.setAttribute("style", "position:relative;height: 100px;width:" + canvasWidth + 'px;');
		canvasArr[0].parentNode.insertBefore(flagContainer, canvasArr[0]);
	}
	var that = this;
	this.flagArr.forEach(function(item, index) {
		var percent = ((MyWavesurfer.GetTimeFloat(item.time) / this.wavesurfer.getDuration()) * 100).toFixed(4);
		console.log("percent", percent);
		var flagItemNode = document.createElement('div');
		flagItemNode.setAttribute("class", "iconfont icon-location");
		flagItemNode.setAttribute("style", "width: 16px;height:16px;position:absolute;top:2px;cursor:pointer;left:calc("+percent+"% - 8px);"+ (item.color ? "color:" + item.color +";" : ""));
		flagItemNode.addEventListener('click', function(event) {
			event = event || window.event;
			event.stopPropagation();
			if(that.flagClickHandler) {
				that.flagClickHandler(index);
			}
		})
		flagContainer.appendChild(flagItemNode);
	})
}

MyWavesurfer.prototype.setFlag = function(flagArr) {
	this.flagArr = flagArr;
	this.renderFlag();
}

MyWavesurfer.TimeFormat = function(timeFloat) {
	if(isNaN(timeFloat)) {
		return '00:00:00';
	}

	var timeInt = Math.floor(timeFloat);
	
	var hoursInt = Math.floor(timeInt / 3600),
		minnutesInt = Math.floor((timeInt - hoursInt * 3600) / 60),
		secondsInt = timeInt % 60;
	var hoursStr = hoursInt > 9 ? hoursInt : ("0" + hoursInt);
	var minutesStr = minnutesInt > 9 ? minnutesInt : ("0" + minnutesInt);
	var secondsStr = secondsInt > 9 ? secondsInt : ("0" + secondsInt);
	return hoursStr + ":" + minutesStr + ":" + secondsStr
}

MyWavesurfer.GetTimeFloat = function(timeStr) {
	var timeRegExp = /^\d{2}:(\d{2}:)?\d{2}$/;
	if(!timeRegExp.test(timeStr)) {
		return 0;
	}
	var timeArr = timeStr.split(":");
	// console.log("timeArr", timeArr);
	if(timeArr.length === 3) {
		return Number(timeArr[0]) * 3600 + Number(timeArr[1]) * 60 + Number(timeArr[2]);
	}
	return Number(timeArr[0]) * 60 + Number(timeArr[1]);
}

